/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * view.java
 *
 * Created on 06/04/2013, 16:21:37
 */
package screen;

import jxl.write.WriteException;
import services.ServiceInformation;
import exportFile.ExportExcel;
import com.google.gson.Gson;

import dataModel.jsonReader.JSONReader;
import dataModel.jsonStructure.Doc;
import dataModel.process.Activity;
import dataModel.process.ProcessModel;
import de.hpi.bpt.graph.algo.rpst.RPST;
import de.hpi.bpt.process.ControlFlow;
import de.hpi.bpt.process.Node;
import java.awt.Desktop;
import java.awt.image.ImageObserver;
import java.io.IOException;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import preprocessing.FormatConverter;
import java.io.File;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import services.IdentifyingHeuristics;

/**
 *
 * @author Bruna
 */
public class view extends javax.swing.JFrame {

    private int returnValue;

    /** Creates new form view */
    public view() {
        initComponents();
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        fileChooser = new javax.swing.JFileChooser();
        pnlPainelGeral = new javax.swing.JPanel();
        pnlHeuristicas = new javax.swing.JPanel();
        chkCluster = new javax.swing.JCheckBox();
        chkWorkflows = new javax.swing.JCheckBox();
        chkRegrasNeocio = new javax.swing.JCheckBox();
        chkMultiplaInstancia = new javax.swing.JCheckBox();
        chkAtisSeq = new javax.swing.JCheckBox();
        pnlArquivo = new javax.swing.JPanel();
        txtCaminhoArquivo = new javax.swing.JTextField();
        lblSelecioneArquivo = new javax.swing.JLabel();
        btnBrowser = new javax.swing.JButton();
        pnlRelatorios = new javax.swing.JPanel();
        btnRelatorioServico = new javax.swing.JButton();
        pnlConsolidacao = new javax.swing.JPanel();
        chkFlows = new javax.swing.JCheckBox();
        chkServPerf = new javax.swing.JCheckBox();
        chkServAtivs = new javax.swing.JCheckBox();

        fileChooser.setFileFilter(new FilterJSON());
        fileChooser.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                fileChooserActionPerformed(evt);
            }
        });

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setTitle("Ferramenta");
        setMinimumSize(new java.awt.Dimension(500, 300));
        getContentPane().setLayout(new java.awt.GridBagLayout());

        pnlPainelGeral.setBorder(javax.swing.BorderFactory.createTitledBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0), 1, true), "Identificação automática de serviços candidatos", javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.DEFAULT_POSITION));
        pnlPainelGeral.setMinimumSize(new java.awt.Dimension(500, 300));
        pnlPainelGeral.setName("Ferramenta"); // NOI18N
        pnlPainelGeral.setLayout(new java.awt.GridBagLayout());

        pnlHeuristicas.setBorder(javax.swing.BorderFactory.createTitledBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0), 1, true), "Selecione as Heurísticas de Identificação de serviços candidatos", javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.DEFAULT_POSITION));
        pnlHeuristicas.setMinimumSize(new java.awt.Dimension(450, 100));
        pnlHeuristicas.setPreferredSize(new java.awt.Dimension(500, 150));
        pnlHeuristicas.setLayout(new java.awt.GridBagLayout());

        chkCluster.setText("Cluster");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        pnlHeuristicas.add(chkCluster, gridBagConstraints);

        chkWorkflows.setText("Workflows");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 4;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        pnlHeuristicas.add(chkWorkflows, gridBagConstraints);

        chkRegrasNeocio.setText("Regras de Negócio");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        pnlHeuristicas.add(chkRegrasNeocio, gridBagConstraints);

        chkMultiplaInstancia.setText("Múltipla Instância");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        pnlHeuristicas.add(chkMultiplaInstancia, gridBagConstraints);

        chkAtisSeq.setText("Atividades Sequenciais");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        pnlHeuristicas.add(chkAtisSeq, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.insets = new java.awt.Insets(10, 0, 0, 0);
        pnlPainelGeral.add(pnlHeuristicas, gridBagConstraints);

        pnlArquivo.setLayout(new java.awt.GridBagLayout());

        txtCaminhoArquivo.setEditable(false);
        txtCaminhoArquivo.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        gridBagConstraints.insets = new java.awt.Insets(1, 10, 0, 0);
        pnlArquivo.add(txtCaminhoArquivo, gridBagConstraints);

        lblSelecioneArquivo.setText("Selecione o arquivo JSON");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.insets = new java.awt.Insets(30, 10, 2, 0);
        pnlArquivo.add(lblSelecioneArquivo, gridBagConstraints);

        btnBrowser.setText("Browse");
        btnBrowser.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnBrowserActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 1;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        gridBagConstraints.insets = new java.awt.Insets(1, 10, 0, 0);
        pnlArquivo.add(btnBrowser, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        pnlPainelGeral.add(pnlArquivo, gridBagConstraints);

        pnlRelatorios.setLayout(new java.awt.GridBagLayout());

        btnRelatorioServico.setText("Gerar Serviços Candidatos");
        btnRelatorioServico.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                btnRelatorioServicoActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.insets = new java.awt.Insets(30, 10, 20, 0);
        pnlRelatorios.add(btnRelatorioServico, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 3;
        pnlPainelGeral.add(pnlRelatorios, gridBagConstraints);

        pnlConsolidacao.setBorder(javax.swing.BorderFactory.createTitledBorder(new javax.swing.border.LineBorder(new java.awt.Color(0, 0, 0), 1, true), "Selecione as heuristicas de consolidação dos serviços candidatos", javax.swing.border.TitledBorder.CENTER, javax.swing.border.TitledBorder.DEFAULT_POSITION));
        pnlConsolidacao.setMinimumSize(new java.awt.Dimension(450, 100));
        pnlConsolidacao.setPreferredSize(new java.awt.Dimension(500, 150));
        pnlConsolidacao.setLayout(new java.awt.GridBagLayout());

        chkFlows.setText("Subfluxos, Número de Raias e Cluster Associados");
        chkFlows.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                chkFlowsActionPerformed(evt);
            }
        });
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        pnlConsolidacao.add(chkFlows, gridBagConstraints);

        chkServPerf.setText("Serviços X Perfis");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        pnlConsolidacao.add(chkServPerf, gridBagConstraints);

        chkServAtivs.setText("Serviços X Atividades");
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.LINE_START;
        pnlConsolidacao.add(chkServAtivs, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 2;
        gridBagConstraints.insets = new java.awt.Insets(10, 0, 0, 0);
        pnlPainelGeral.add(pnlConsolidacao, gridBagConstraints);

        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
        getContentPane().add(pnlPainelGeral, gridBagConstraints);
        pnlPainelGeral.getAccessibleContext().setAccessibleName("");

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void btnBrowserActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnBrowserActionPerformed
        returnValue = fileChooser.showOpenDialog(this);
        if (returnValue == JFileChooser.APPROVE_OPTION) {
            File file = fileChooser.getSelectedFile();
            txtCaminhoArquivo.setText(file.getName());
        } else {
            System.out.println("File access cancelled by user.");
        }

    }//GEN-LAST:event_btnBrowserActionPerformed

    private void fileChooserActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fileChooserActionPerformed
    }//GEN-LAST:event_fileChooserActionPerformed

    private void btnRelatorioServicoActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_btnRelatorioServicoActionPerformed

          boolean servConsol = false;
          HeuristicsSelected heurisSelec = new HeuristicsSelected();
        if (chkServAtivs.isSelected() || chkServPerf.isSelected() || chkFlows.isSelected()) {
            servConsol = true;
        }
        
        if (!chkAtisSeq.isSelected() && !chkCluster.isSelected() && !chkMultiplaInstancia.isSelected()
                && !chkRegrasNeocio.isSelected() && !chkWorkflows.isSelected() && servConsol) {
            JOptionPane.showMessageDialog(null, "Selecione pelo menos uma heurística de identificação", "Erro!", JOptionPane.ERROR_MESSAGE);
        } else {
            try {

                ProcessModel model = readAndWriteFile();

                ExportExcel file = new ExportExcel();
                file.setOutputFile("ExcelFile/services.xls");

                List<List> allServices = new LinkedList<List>();
                List<ServiceInformation> servicesInfos = new LinkedList<ServiceInformation>();

                if (chkRegrasNeocio.isSelected()) {
                    heurisSelec.setRegrasNegocioSelected(true);
                    System.out.println("-----//  Regras de Negócio  //-----");
                    servicesInfos = IdentifyingHeuristics.findBusinessRules(model);
                    if (!servicesInfos.isEmpty()) {
                        allServices.add(servicesInfos);
                    }
                }

                if (chkMultiplaInstancia.isSelected()) {
                    heurisSelec.setMultiplaInstanciaSelected(true);
                    System.out.println("-----//  Multipla Instância  //-----");
                    servicesInfos = IdentifyingHeuristics.findMultipleInstance(model);
                    if (!servicesInfos.isEmpty()) {
                        allServices.add(servicesInfos);
                    }
                }

                List<ServiceInformation> finalClusterConsolidated = new LinkedList<ServiceInformation>();
                if (chkCluster.isSelected()) {
                    heurisSelec.setClusterSelected(true);
                    System.out.println("-----//  Data Store  //-----");
                    servicesInfos = IdentifyingHeuristics.findDataStore(model);
                    if (!servicesInfos.isEmpty()) {
                        //List<ServiceInformation> listServicesCluster = IdentifyingHeuristics.deleteSameServices(servicesInfos);
                        List<ServiceInformation> listAuxServicesCluster = new LinkedList<ServiceInformation>();
                        //listAuxServicesCluster.addAll(listServicesCluster);
                        listAuxServicesCluster.addAll(servicesInfos);
                        finalClusterConsolidated = IdentifyingHeuristics.consolidateClusterServices(listAuxServicesCluster);
                        //allServices.add(finalClusterServices);
                        //allServices.add(listServicesCluster);
                        allServices.add(servicesInfos);
                    }
                }

                if (chkAtisSeq.isSelected()) {
                    heurisSelec.setAtividadesSequenciaisSelected(true);
                    IdentifyingHeuristics.transformToAdjancencyList(model);

                    System.out.println("-----//  Atividades Sequenciais  //-----");
                    List<List> ativsSeq = IdentifyingHeuristics.findSequentialActivities(model);
                    List<List> servicesActivities = new LinkedList<List>();
                    servicesActivities = IdentifyingHeuristics.printAndSetSequentialActivities(ativsSeq, model);
                    for (List list : servicesActivities) {
                        allServices.add(list);
                    }
                }

                if (chkWorkflows.isSelected()) {
                    heurisSelec.setWorkflowsSelected(true);
                    int counter = 0;
                    RPST<ControlFlow, Node> rpst = transformToRPST(model, counter);
                    System.out.println("-----//  Heuristica de Workflow  //-----");
                    List<ServiceInformation> servicesWorkflow = new LinkedList<ServiceInformation>();
                    IdentifyingHeuristics.findWokflowHeuristic(rpst.getRoot(), rpst, 0, model, servicesWorkflow);
                    List<ServiceInformation> listServicesWorkflow = IdentifyingHeuristics.deleteSameServices(servicesWorkflow);                    
                    if (chkFlows.isSelected()) {
                        heurisSelec.setSubflowsSelected(true);
                        listServicesWorkflow = IdentifyingHeuristics.countSubflows(listServicesWorkflow);
                        allServices.add(listServicesWorkflow);
                    }
                    else{
                        allServices.add(listServicesWorkflow);
                    }
                }

                file.write(allServices,heurisSelec);
                openFile(file);

                List<List> servicesClusterConsolidated = new LinkedList<List>();
                servicesClusterConsolidated.add(finalClusterConsolidated);

                HashMap<Integer, Activity> allActivities = model.getActivities();
                List<String> actsName = new LinkedList<String>();
                List<String> actsRepeatName = new LinkedList<String>();


                for (int keyMap : allActivities.keySet()) {
                    actsName.add(allActivities.get(keyMap).getLabel());
                }

                for (int i = 0; i < actsName.size(); i++) {
                    for (int j = i + 1; j < actsName.size(); j++) {

                        if (actsName.get(i).equalsIgnoreCase(actsName.get(j))) {
                            actsRepeatName.add(actsName.get(i));
                        }
                    }

                }
                actsName.removeAll(actsRepeatName);
                actsName.addAll(actsRepeatName);

                if(servConsol){
                    if(chkServAtivs.isSelected()){
                        heurisSelec.setServAtivSelected(true);
                    }
                    if(chkServPerf.isSelected()){
                        heurisSelec.setServPerfisSelected(true);
                    }
                    ExportExcel fileServConsol = new ExportExcel();
                    fileServConsol.setOutputFile("ExcelFile/servicesConsolidated.xls");
                    fileServConsol.writeConsolidated(servicesClusterConsolidated, allServices, actsName, heurisSelec);
                    openFile(fileServConsol);
                }

            } catch (IOException ex) {
                JOptionPane.showMessageDialog(null, ex.getMessage(), "Erro!", JOptionPane.ERROR_MESSAGE);
                System.out.println("Erro!" + ex.getMessage());
            } catch (WriteException ex) {
                JOptionPane.showMessageDialog(null, ex.getMessage(), "Erro!", JOptionPane.ERROR_MESSAGE);
                System.out.println("Erro!" + ex.getMessage());
            }
        }


    }//GEN-LAST:event_btnRelatorioServicoActionPerformed

    private void chkFlowsActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_chkFlowsActionPerformed
        // TODO add your handling code here:
        if (!chkWorkflows.isSelected() && chkFlows.isSelected()) {
            chkWorkflows.setSelected(true);
        }
    }//GEN-LAST:event_chkFlowsActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(view.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(view.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(view.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(view.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new view().setVisible(true);
            }
        });
    }

    public static RPST transformToRPST(ProcessModel model, int counter) {
        // Convert to RPST
        FormatConverter formatConverter = new FormatConverter();
        de.hpi.bpt.process.Process p = formatConverter.transformToRPSTFormat(model);
        RPST<ControlFlow, Node> rpst = new RPST<ControlFlow, Node>(p);
        return rpst;
    }

    public ProcessModel readAndWriteFile() {

        String path = fileChooser.getSelectedFile().getPath();

        JSONReader reader = new JSONReader();
        Gson gson = new Gson();

        Doc modelDoc;
        try {
            modelDoc = gson.fromJson(reader.getJSONStringFromFile(path), Doc.class);
            if (modelDoc.getChildShapes() != null) {
                reader.init();
                reader.getIntermediateProcessFromFile(modelDoc);
                ProcessModel model = reader.getProcessModelFromIntermediate();
                try {
                    model.normalize();
                    model.normalizeEndEvents();
                    return model;
                } catch (Exception e) {
                    System.out.println("Error: Normalization impossible");
                    e.printStackTrace();
                }
            }
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(null, ex.getMessage(), "Erro!", JOptionPane.ERROR_MESSAGE);
            System.out.println("Erro!" + ex.getMessage());
        } catch (TransformerException ex) {
            JOptionPane.showMessageDialog(null, ex.getMessage(), "Erro!", JOptionPane.ERROR_MESSAGE);
            System.out.println("Erro!" + ex.getMessage());
        } catch (ParserConfigurationException ex) {
            JOptionPane.showMessageDialog(null, ex.getMessage(), "Erro!", JOptionPane.ERROR_MESSAGE);
            System.out.println("Erro!" + ex.getMessage());
        }
        return null;
    }

    public void openFile(ExportExcel file) {
        File arq = file.getFile();
        try {
            Desktop.getDesktop().open(arq);
        } catch (IOException ex) {
            JOptionPane.showMessageDialog(null, ex.getMessage(), "Erro!", JOptionPane.ERROR_MESSAGE);
            System.out.println("Erro!" + ex.getMessage());
        }
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JButton btnBrowser;
    private javax.swing.JButton btnRelatorioServico;
    private javax.swing.JCheckBox chkAtisSeq;
    private javax.swing.JCheckBox chkCluster;
    private javax.swing.JCheckBox chkFlows;
    private javax.swing.JCheckBox chkMultiplaInstancia;
    private javax.swing.JCheckBox chkRegrasNeocio;
    private javax.swing.JCheckBox chkServAtivs;
    private javax.swing.JCheckBox chkServPerf;
    private javax.swing.JCheckBox chkWorkflows;
    private javax.swing.JFileChooser fileChooser;
    private javax.swing.JLabel lblSelecioneArquivo;
    private javax.swing.JPanel pnlArquivo;
    private javax.swing.JPanel pnlConsolidacao;
    private javax.swing.JPanel pnlHeuristicas;
    private javax.swing.JPanel pnlPainelGeral;
    private javax.swing.JPanel pnlRelatorios;
    private javax.swing.JTextField txtCaminhoArquivo;
    // End of variables declaration//GEN-END:variables
}
